#! /usr/bin/env python3
# -*- coding:utf-8 -*-

'metaclass元类实现orm'
import doctest
import logging
logging.basicConfig(level=logging.INFO)  # debug info warning error


class Field(object):
    def __init__(self, name, column_type):
        self.name = name
        self.column_type = column_type

    def __str__(self):
        return '<%s:%s>' % (self.__class__.__name__, self.name)


class StringField(Field):
    def __init__(self, name):
        super(StringField, self).__init__(name, 'varchar(100)')


class IntegerField(Field):
    def __init__(self, name):
        super(IntegerField, self).__init__(name, "int")


class ModelMetaclass(type):
    def __new__(cls, name, bases, attrs):
        if name == 'Model':
            return type.__new__(cls, name, bases, attrs)
        print("found Model: %s" % name)
        mapping = dict()
        for k, v in attrs.items():
            if isinstance(v, Field):
                mapping[k] = v
                print("found mapping: %s ==> %s" % (k, v))
        for x in mapping.keys():
            attrs.pop(x)
        attrs['__mapping__'] = mapping
        attrs['__table__'] = 't_' + name.lower()
        return type.__new__(cls, name, bases, attrs)


class Model(dict, metaclass=ModelMetaclass):
    def __init__(self, **kw):
        super(Model, self).__init__(**kw)

    def __getattr__(self, name):
        try:
            return self[name]
        except BaseException as e:
            logging.exception(e)
            raise AttributeError("值不存在")

    def __setattr__(self, name, value):
        self[name] = value

    def save(self):
        field = []
        params = []
        args = []
        for k, v in self.__mapping__.items():
            field.append(v.name)
            params.append('?')
            args.append(getattr(self, k, None))
        sql = "insert into %s (%s) values (%s)" % (
            self.__table__, ", ".join(field), ", ".join(params))
        print("sql:%s" % sql)
        print("args:%s" % args)


class User(Model):
    id = IntegerField('id')
    name = StringField('name')
    email = StringField('email')
    password = StringField('password')


user = User(id=1, name='pengxj', email='pengxj@163.com', password='1111')
user.save()


def test(s):
    '''
    测试打印，如：
    >>> test("1111")
    Traceback (most recent call last):
        ...
    ValueError: 1111
    >>> test("2222")
    input: 2222
    '''
    logging.info('test')
    if(s == '1111'):
        raise ValueError("1111")
    print("input: %s" % s)


doctest.testmod()
